package com.lanyou.esb.cook.proxy.redis.proxy.impl;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.exceptions.JedisException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.lanyou.esb.cook.proxy.common.Constants4Redis;
import com.lanyou.esb.cook.proxy.entity.IfAlarm;
import com.lanyou.esb.cook.proxy.redis.JedisPoolUtils;
import com.lanyou.esb.cook.proxy.redis.proxy.base.BaseStrJedisProxy;

/**
 * 接口重复告警Redis操作代理
 * 
 * @author Davey.wu
 */
public class IfAlarmRepeatJedisProxy extends BaseStrJedisProxy<IfAlarm> {
	/** 更新键后缀 **/
	private static final String UPDATE_SUFFIX = Constants4Redis.SUFFIX_UPDATE;
	/** 重复对象键后缀 **/
	private static final String REPEAT_SUFFIX = Constants4Redis.SUFFIX_REPEAT;
	/** 重复次数键后缀 **/
	private static final String NUM_SUFFIX = Constants4Redis.SUFFIX_NUMBER;
	/** 接口告警更新过期时间（秒） **/
	private int UPDATE_TIMEOUT = Constants4Redis.REDIS_TIMEOUT_IF_ALARM_REPEAT_UPDATE;
	/** 接口告警重复次数过期时间（秒） **/
	private int NUM_TIMEOUT = Constants4Redis.REDIS_TIMEOUT_IF_ALARM_REPEAT_UPDATE;

	public IfAlarmRepeatJedisProxy() {
		this.setTimeOut(Constants4Redis.REDIS_TIMEOUT_IF_ALARM_REPEAT_INTERVAL);
	}

	@Override
	public String getKey(String value) {
		return value;
	}

	@Override
	public String getKeyFromObject(IfAlarm value) {
		/**
		 * 1，目标系统编码相同；<br>
		 * 2，接口编码相同；<br>
		 * 3，接口版本相同；<br>
		 * 4，调用方系统编码相同；<br>
		 * 5，告警类型相同；<br>
		 * 6，告警等级相同；<br>
		 **/
		StringBuilder builder = new StringBuilder();
		builder.append(value.getSystemCode());
		builder.append(KEY_SEPARATOR);
		builder.append(value.getIfCode());
		builder.append(KEY_SEPARATOR);
		builder.append(value.getIfVersion());
		builder.append(KEY_SEPARATOR);
		builder.append(value.getCallSystemCode());
		builder.append(KEY_SEPARATOR);
		builder.append(value.getAlarmType());
		builder.append(KEY_SEPARATOR);
		builder.append(value.getAlarmLevel());
		builder.append(REPEAT_SUFFIX);
		return builder.toString();
	}

	/**
	 * 更新接口告警
	 * 
	 * @param value
	 * @throws JsonProcessingException
	 */
	public void update(IfAlarm value) throws JedisException,
			JsonProcessingException {
		String key = getKeyFromObject(value);
		String upKey = generateUpdateKey(key);
		String numKey = generateNumKey(value);
		String json = toJson(value);

		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			Pipeline p = jedis.pipelined();
			// 保存对象
			p.setex(key, this.getTimeOut(), json);
			p.setex(upKey, this.UPDATE_TIMEOUT, json);
			// 重设重复次数有效期
			p.expireAt(numKey, this.NUM_TIMEOUT);
			// // 增加重复次数
			//p.incrBy(numKey, 1l);
			p.sync();
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	public void incr(String key, long value) {
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			jedis.incrBy(key, value);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	/**
	 * 获取重复次数
	 * 
	 * @param alarm
	 * @throws JsonProcessingException
	 */
	public int getRepeat(IfAlarm alarm) throws JedisException,
			JsonProcessingException {
		String key = generateNumKey(alarm);
		String result = "";
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return 0;
		}
		boolean broken = false;
		try {
			result = jedis.get(key);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		try {
			return Integer.parseInt(result);
		} catch (Exception e) {
			return 0;
		}
	}

	/**
	 * 生成对象更新键
	 * 
	 * @param alarm
	 * @return
	 */
	public String generateUpdateKey(IfAlarm alarm) {
		return getKeyFromObject(alarm) + UPDATE_SUFFIX;
	}

	/**
	 * 生成重复次数键
	 * 
	 * @param alarm
	 * @return
	 */
	public String generateNumKey(IfAlarm alarm) {
		return alarm.getId() + NUM_SUFFIX;
	}

	/**
	 * 生成重复次数键
	 * 
	 * @param key
	 * @return
	 */
	public String generateNumKey(String key) {
		return key + NUM_SUFFIX;
	}

	/**
	 * 生成对象更新键
	 *
	 * @param key
	 * @return
	 */
	private String generateUpdateKey(String key) {
		return key + UPDATE_SUFFIX;
	}
}
